package top.amot.forceview.force

import top.amot.forceview.layout.I_Layout

class ForceY : AbstractForce() {
    private lateinit var strengths: FloatArray
    private lateinit var yz: FloatArray
    private var yCalculation: NodeCalculation? = null
    private var strengthCalculation: NodeCalculation? = null
    override fun initialize(layout: I_Layout) {
        super.initialize(layout)
        initialize()
    }

    override fun apply(alpha: Float) {
        nodes.forEachIndexed { i, node ->
            node.vy += (yz[i] - node.y) * strengths[i] * alpha
        }
    }

    fun y(c: NodeCalculation?): ForceY {
        yCalculation = c
        return this
    }

    fun strength(c: NodeCalculation?): ForceY {
        strengthCalculation = c
        return this
    }

    private fun initialize() {
        val size = nodes.size
        strengths = FloatArray(size)
        yz = FloatArray(size)
        for (i in 0 until size) {
            yz[i] = y(i)
            strengths[i] = strength(i)
        }
    }

    private fun y(i: Int): Float {
        return yCalculation?.calculateNode(nodes[i])?: 0.0f
    }

    private fun strength(i: Int): Float {
        return  strengthCalculation?.calculateNode(nodes[i])?:DEFAULT_STRENGTH
    }

    companion object {
        const val NAME = "Y"
        private const val DEFAULT_STRENGTH = 0.1f
    }
}